package com.example.deploysinggle.test1.common.general;

import com.example.deploysinggle.test1.common.constants.StringLengthConstant;
import com.example.deploysinggle.test1.common.context.QiuContext;
import com.example.deploysinggle.test1.common.enums.ErrorEnum;
import com.example.deploysinggle.test1.common.exeptions.BizException;
import com.example.deploysinggle.test1.common.general.APIConfiguration;
import com.example.deploysinggle.test1.common.req.BaseApiRequest;
import com.example.deploysinggle.test1.common.postconstruct.CommonCache;
import com.example.deploysinggle.test1.common.redis.CacheService;
import com.example.deploysinggle.test1.common.util.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * @author Administrator
 * @version 1.0
 * @description: TODO
 * @date 2024/12/15 19:29
 */
public interface DeafaltApiCheckedInterface {
    String IP_KEY = "ip_filter_";
    // clientId
    // tamstampce
    // random
    default void handle(BaseApiRequest baseApiRequest) throws Exception{
        judgeClientId(baseApiRequest.getClientId());
        judgeRandomTimes(baseApiRequest.getRandom());
        judgeTimstamp(baseApiRequest.getTimestamp());
        judgeOriginalIpUsedTimes(IP_KEY + QiuContext.getOriIp());
        judgeSign(baseApiRequest);
    }

    // md5 key  根据 前三个生成的一个加密串
    APIConfiguration getApiConfiguration();
//判断时间戳
default void judgeTimstamp(Long timstamp) throws Exception{
    Optional.ofNullable(timstamp)
            .filter(s -> s>0)
            .orElseThrow(() -> new RuntimeException());
     long currentTimeMillis = System.currentTimeMillis();

     if(Math.abs(currentTimeMillis - timstamp) >5*60*1000){
         throw new RuntimeException();
     }
}
// 当断租户
default void judgeClientId(Integer clientId) throws Exception{
    Optional.ofNullable(clientId)
            .filter(s -> s>0)
            .orElseThrow(() -> new RuntimeException());
    //拿到缓存map
     Map<Integer, List<String>> urlMap = CommonCache.getUrlMap();
     List<String> urlStrings = urlMap.get(clientId);
     Optional.ofNullable(urlMap)

             .filter(a -> !CollectionUtils.isEmpty(urlStrings)
             && urlStrings.contains(QiuContext.getReqPath()))
             .orElseThrow(() -> new RuntimeException());
}


default void judgeRandomTimes(String random) throws BizException {
    Optional.ofNullable(random)
            .filter(s -> StringUtils.length(s) < StringLengthConstant.STRING_MIN_MID_LENGTH)
            .orElseThrow(() -> new RuntimeException());

    //从redis 获取 random 访问次数
     Long randomTime = Optional.ofNullable(getCacheService().get(random, Long.class))
            .orElse(0L);

     if(randomTime > getApiConfiguration().getRandomTimes()){
         //抛出一个 验证码验证失败异常
         throw new BizException(ErrorEnum.API_RANDOM_KEY_ERROR);
     }
}
// 每次请求结束要向redis设置
default void setRandomUsedTimes(String random){
    if(getCacheService().get(random) == null){
        getCacheService().set(random, 1, getApiConfiguration().getRandomExpireTime()) ;
    }
    else
    {
        getCacheService().increment(random, 1L);
    }
}
//校验登录
default void judgeSign(BaseApiRequest baseApiRequest) {
Optional.ofNullable(baseApiRequest.getKey())
        .orElseThrow(() -> new RuntimeException());
    String sign = MD5Util.calculateMD5(
            "clientId=" + baseApiRequest.getClientId() +"&random=" + baseApiRequest.getRandom() +
                    "&timestamp=" + baseApiRequest.getTimestamp()
    );
    if(!Objects.equals(sign,baseApiRequest.getKey())){
        throw new RuntimeException();
    }
}

default void judgeOriginalIpUsedTimes(String realIpKey) throws Exception{
     Long randomTimes = Optional.ofNullable(getCacheService().get(realIpKey, Long.class)).orElse(0L);
    if(randomTimes > getApiConfiguration().getIpTimes()){
        throw new RuntimeException();
    }
}

default CacheService getCacheService(){
    return getApiConfiguration().getCacheService();
}

}
